package com.intermancer.predictor.experiment.prime;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;

public class OptionHandler {

	public static final String REPO_OPTION = "r";
	public static final String DATA_OPTION = "d";
	private static final String LIFECYCLES_OPTION = "l";
	private static final String CHANNEL_OFFSET_OPTION = "c";
	private static final String LOOKAHEAD_OPTION = "a";
	private static final String WORKING_STORE_SIZE_OPTION = "w";
	private static final String PERSIST_WORKING_STORE_OPTION = "p";
	private static final String TIMEBOX_OPTION = "t";

	public static boolean handleArguments(String[] args, Context context) {
		Options options = buildOptions();
		return configureContext(args, options, context);
	}

	private static boolean configureContext(String[] args, Options options,
			Context context) {
		HelpFormatter formatter = new HelpFormatter();
		try {
			CommandLineParser parser = new PosixParser();
			CommandLine command = parser.parse(options, args);
			if (!validateCommandLine(command)) {
				formatter.printHelp("ExperimentPrime", options);
				return false;
			}
			context.put("repositoryPath", command.getOptionValue(REPO_OPTION));
			if (!context.getRepositoryPath().endsWith("/")) {
				context.setRepositoryPath(context.getRepositoryPath() + "/");
			}
			context.put("dataSourcePath", command.getOptionValue(DATA_OPTION));
			context.put("lifecycles", new Integer(command
					.getOptionValue(LIFECYCLES_OPTION)));
			context.put("channelOffset", new Integer(command
					.getOptionValue(CHANNEL_OFFSET_OPTION)));
			context.put("lookahead", new Integer(command
					.getOptionValue(LOOKAHEAD_OPTION)));
			if (command.hasOption(WORKING_STORE_SIZE_OPTION)) {
				context.put("workingStoreSize", new Integer(command
						.getOptionValue(WORKING_STORE_SIZE_OPTION)));
			}
			return true;
		} catch (Exception e) {
			System.err.println("Exception in processing options");
			e.printStackTrace(System.err);
			formatter.printHelp("ExperimentPrime", options);
			return false;
		}
	}

	private static boolean validateCommandLine(CommandLine command) {
		return command.hasOption(REPO_OPTION) && command.hasOption(DATA_OPTION)
				&& command.hasOption(CHANNEL_OFFSET_OPTION)
				&& command.hasOption(LIFECYCLES_OPTION)
				&& command.hasOption(LOOKAHEAD_OPTION);
	}

	private static Options buildOptions() {
		Options options = new Options();

		options
				.addOption(getOption(REPO_OPTION, true, true, "repository path"));
		options.addOption(getOption(DATA_OPTION, true, true, "data file"));
		options.addOption(getOption(LIFECYCLES_OPTION, true, false,
				"lifecycles"));
		options.addOption(getOption(CHANNEL_OFFSET_OPTION, true, true,
				"channel offset"));
		options
				.addOption(getOption(LOOKAHEAD_OPTION, true, true, "look ahead"));
		options.addOption(getOption(WORKING_STORE_SIZE_OPTION, true, false,
				"working store size"));
		options.addOption(getOption(PERSIST_WORKING_STORE_OPTION, false, false,
				"persist working store"));
		options.addOption(getOption(TIMEBOX_OPTION, false, false,
				"turn on timebox limiting"));

		return options;
	}

	private static Option getOption(String optionName, boolean hasArgument,
			boolean isRequired, String description) {
		Option option = new Option(optionName, hasArgument, description);
		option.setRequired(isRequired);
		return option;
	}

}
